<template>
  <div>
    <div class="upload-image">
      <div class="images">
        <div v-if="items" class="images-item">
          <el-image
              :fit="fit"
              :src="items"
              :preview-src-list="[items]"
              append-to-body
              hide-on-click-modal
          />
          <div class="operate">
            <el-tooltip content="删除" placement="top">
              <i class="el-icon-close" @click="bindRemove"></i>
            </el-tooltip>
          </div>
        </div>
      </div>
      <div
          :style="{
          width: width,
          height: height,
        }"
      >
        <el-upload
            v-loading="loading"
            element-loading-text="图片上传中"
            v-if="!items"
            class="avatar-uploader"
            :multiple="false"
            :show-file-list="false"
            :before-upload="beforeAvatarUpload"
            accept="image/*"
        >
          <i class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
      </div>
      <DialogCutter
          ref="cropper"
          v-if="dialogStatus"
          :width="cropperWidth"
          :height="cropperHeight"
          @success="bindSuccess"
          @closed="dialogClosed"
      />
    </div>
    <div class="placeholder">{{ placeholder }}</div>
  </div>
</template>

<script>
import DialogCutter from "./DialogCropper.vue";
import {ossUploadFileApi} from "@/api/setup/oss";

export default {
  name: "UploadImage",
  components: {
    DialogCutter,
  },
  props: {
    value: {
      type: String,
      default: "",
    },
    preview: {
      type: String,
      default: "",
    },
    limit: {
      type: Number,
      default: 1,
    },
    placeholder: {
      type: String,
      default: "",
    },
    width: {
      type: String,
      default: "200px",
    },
    height: {
      type: String,
      default: "200px",
    },
    fit: {
      type: String,
      validator: function (value) {
        return ["fit", "fill", "contain", "cover", "none", "scale-down"].indexOf(value) !== -1;
      },
      default: "fill",
    },
    file: {
      type: String,
      default: "file",
    },
    data: {
      type: Object,
      default: () => ({
        tplCode: "",
        prefix: "pic",
        renamed: null,
      }),
    },
    cropperWidth: {
      type: String,
      default: "400px",
    },
    cropperHeight: {
      type: String,
      default: "300px",
    },
    isCropper: {
      type: Boolean,
      default: false,
    },
    maxSize: {
      type: Number,
      default: 1,
    },
  },
  computed: {
    items() {
      return this.preview;
    },
  },
  data() {
    return {
      loading: false,
      dialogStatus: false,
    };
  },
  methods: {
    beforeAvatarUpload(file) {
      if (this.isCropper) {
        this.dialogStatus = true;
        this.$nextTick(() => {
          this.$refs.cropper.init(file);
        });
      } else {
        this.uploadFile(file);
      }
      return false;
    },
    bindSuccess(data) {
      const relativePath = data?.bizData?.relativePath;
      const absolutePath = data?.bizData?.absolutePath;

      if (relativePath && absolutePath) {
        this.$emit("update:value", relativePath);
        this.$emit("update:preview", absolutePath);
      }
    },
    dialogClosed() {
      this.dialogStatus = false;
    },
    bindRemove() {
      this.$emit("update:value", "");
      this.$emit("update:preview", "");
    },
    upload(file) {
      const formData = new FormData();
      formData.append(this.file, file);
      Object.keys(this.data).forEach(key => {
        formData.append(key, this.data[key]);
      });
      return ossUploadFileApi(formData);
    },
    uploadFile(file) {
      if (file.size / 1024 / 1024 < this.maxSize) {
        this.loading = true;
        this.upload(file).then((res) => {
          this.bindSuccess(res);
        }).finally(() => {
          this.loading = false;
        });
      } else {
        this.$message.error(`上传图片大小不能超过${this.maxSize}MB!`);
      }
    },
  },
};
</script>

<style scoped>
.images {
  display: flex;
}

.images-item {
  position: relative;
  margin-bottom: 10px;
  margin-right: 10px;
  width: 200px;
  height: 200px;
  border-radius: 4px;
  overflow: hidden;
}

.images-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.images-item .operate i {
  position: absolute;
  padding: 2px;
  top: 0;
  right: 0;
  color: #fff;
  font-size: 14px;
  cursor: pointer;
  vertical-align: middle;
  background-color: #f56c6c;
  border-radius: 0 0 0 4px;
  opacity: 0.8;
}

.images-item .operate i:hover {
  opacity: 1;
}

.upload-image {
  display: flex;
  flex-wrap: wrap;
}

.upload-image .avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.upload-image .avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.upload-image .avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 200px;
  height: 200px;
  line-height: 200px;
  text-align: center;
}

.upload-image .avatar {
  width: 200px;
  height: 200px;
  display: block;
}
</style>
